package com.cupk.rotaryguard.monitor.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cupk.common.base.config.RedisKeyContant;
import com.cupk.common.base.utils.result.Result;
import com.cupk.common.base.utils.result.ResultGenerator;
import com.cupk.rotaryguard.monitor.entity.DeviceInfo;
import com.cupk.rotaryguard.monitor.entity.vo.DeviceVo;
import com.cupk.rotaryguard.monitor.mapper.DeviceMapper;
import com.cupk.rotaryguard.monitor.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author tjy
 * @date 2023/3/26
 * @apiNote
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, DeviceInfo>
        implements DeviceService {

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 获取设备信息
     *
     * @return
     */
    @Override
    public Result getDeviceInfo() {
        String devicesJson = stringRedisTemplate.opsForValue().get(RedisKeyContant.DEVICE_INFO);
        if (StringUtils.isNotBlank(devicesJson)) {
            List<DeviceInfo> deviceInfos = JSONArray.parseArray(devicesJson, DeviceInfo.class);
            return ResultGenerator.genSuccessResultPage(deviceInfos, deviceInfos.size());
        }
        List<DeviceInfo> deviceInfos = deviceMapper.selectList(null);
        if (ObjectUtils.isNotEmpty(deviceInfos)) {
            String deviceJson = JSON.toJSONString(deviceInfos);
            stringRedisTemplate.opsForValue().set(RedisKeyContant.DEVICE_INFO, deviceJson, RedisKeyContant.DEVICES_INFO_TTL, TimeUnit.MINUTES);
            return ResultGenerator.genSuccessResultPage(deviceInfos, deviceInfos.size());
        }
        return ResultGenerator.genFailResult(null, "暂无结果");
    }

    /**
     * 根据id查询设备信息
     *
     * @param id
     * @return
     */
    @Override
    public Result getDeviceInfoById(Long id) {
        String deviceJson = stringRedisTemplate.opsForValue().get(RedisKeyContant.DEVICE_INFO + ":" + id);
        if (StringUtils.isNotBlank(deviceJson)) {
            DeviceInfo deviceInfo = JSONObject.parseObject(deviceJson, DeviceInfo.class);
            return ResultGenerator.genSuccessResult(deviceInfo, "获取成功");
        }
        DeviceInfo device = deviceMapper.selectById(id);
        if (ObjectUtils.isNotEmpty(device)) {
            deviceJson = JSON.toJSONString(device);
            stringRedisTemplate.opsForValue().set(RedisKeyContant.DEVICE_INFO + ":" + id, deviceJson, RedisKeyContant.DEVICES_INFO_TTL, TimeUnit.MINUTES);
            return ResultGenerator.genSuccessResult(device);
        }
        return ResultGenerator.genFailResult(null, "暂无结果");
    }

    /**
     * 根据型号、频率、功率查询设备状态
     *
     * @param pageNum
     * @param pageSize
     * @param deviceModel
     * @param deviceFrequency
     * @param devicePower
     * @param status
     * @return
     */
    @Override
    public Result getDeviceInfoByParams(
            Integer pageNum, Integer pageSize,
            String deviceModel, BigDecimal deviceFrequency,
            BigDecimal devicePower, Integer status) {
        //redis设备信息key值
        String deviceInfoPageKey = RedisKeyContant.DEVICE_INFO + ":"
                + pageNum + ":"
                + pageSize + ":"
                + deviceModel + ":"
                + deviceFrequency + ":"
                + devicePower + ":"
                + status;
        String deviceJson = stringRedisTemplate.opsForValue()
                .get(deviceInfoPageKey);
        if (StringUtils.isNotBlank(deviceJson)) {
            List<DeviceInfo> deviceInfos = JSON.parseArray(deviceJson, DeviceInfo.class);
            IPage<DeviceInfo> deviceInfoIPage = new Page<>(pageNum, pageSize);
            deviceInfoIPage.setRecords(deviceInfos);
            deviceInfoIPage.setTotal(deviceInfos.size());

            return ResultGenerator.genSuccessResult(deviceInfoIPage, "获取成功");
        }
        QueryWrapper<DeviceInfo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(deviceModel)) {
            queryWrapper.like("device_model", deviceModel);
        }
        if (ObjectUtils.isNotEmpty(deviceFrequency)) {
            queryWrapper.like("device_frequency", deviceFrequency);
        }
        if (ObjectUtils.isNotEmpty(devicePower)) {
            queryWrapper.like("device_power", devicePower);
        }
        if (ObjectUtils.isNotEmpty(status)) {
            queryWrapper.eq("status", status);
        }
        IPage<DeviceInfo> pageData = new Page<>(pageNum, pageSize);
        IPage<DeviceInfo> deviceInfoIPage = deviceMapper.selectPage(pageData, queryWrapper);
        if (ObjectUtils.isNotEmpty(deviceInfoIPage)) {
            stringRedisTemplate.opsForValue()
                    .set(deviceInfoPageKey, JSON.toJSONString(deviceInfoIPage.getRecords()),
                            RedisKeyContant.DEVICES_INFO_TTL, TimeUnit.MINUTES);
            return ResultGenerator.genSuccessResult(deviceInfoIPage, "获取成功");
        }
        return ResultGenerator.genFailResult(null, "结果为空");
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Override
    public Result delDevice(List<Integer> ids) {
        deviceMapper.deleteBatchIds(ids);
        Set keys = stringRedisTemplate.keys(RedisKeyContant.DEVICE_INFO + "*");
        stringRedisTemplate.delete(keys);
        return ResultGenerator.genSuccessResult(null, "删除成功");
    }

    /**
     * 添加设备
     *
     * @param deviceVo
     * @return
     */
    @Override
    public Result addDevice(DeviceVo deviceVo) {
        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.setDeviceFrequency(deviceVo.getDeviceFrequency());
        deviceInfo.setDeviceModel(deviceVo.getDeviceModel());
        deviceInfo.setDevicePower(deviceVo.getDevicePower());
        try {
            deviceMapper.insert(deviceInfo);
        } catch (Exception e) {
            log.info("错误异常信息：", e);
            return ResultGenerator.genFailResult(null, "添加失败" + e.getMessage());
        }
        Set keys = stringRedisTemplate.keys(RedisKeyContant.DEVICE_INFO + "*");
        stringRedisTemplate.delete(keys);
        return ResultGenerator.genSuccessResult(deviceVo, "添加成功！");
    }

    /**
     * 更新设备信息
     *
     * @param id
     * @param deviceModel
     * @param deviceFrequency
     * @param devicePower
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result chDeviceInfo(Long id, String deviceModel,
                               BigDecimal deviceFrequency,
                               BigDecimal devicePower) {
        DeviceInfo deviceInfo = deviceMapper.selectById(id);
        if (ObjectUtils.isNotEmpty(deviceInfo)) {
            deviceInfo.setDevicePower(devicePower);
            deviceInfo.setDeviceModel(deviceModel);
            deviceInfo.setDeviceFrequency(deviceFrequency);
        }
        try {
            deviceMapper.updateById(deviceInfo);
        } catch (Exception e) {
            log.error(e.getMessage());
            ResultGenerator.genFailResult(e.getMessage(), "更新失败");
        }
        Set keys = stringRedisTemplate.keys(RedisKeyContant.DEVICE_INFO + "*");
        stringRedisTemplate.delete(keys);
        return ResultGenerator.genSuccessResult(deviceInfo, "更新成功");
    }

    /**
     * 根据id删除设备信息
     *
     * @param id
     * @return
     */
    @Override
    public Result delDeviceById(Integer id) {
        QueryWrapper<DeviceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        DeviceInfo deviceInfo = deviceMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(deviceInfo)) {
            return ResultGenerator.genFailResult(null, "删除失败,id不存在");
        }
        deviceMapper.deleteById(id);
        Set keys = stringRedisTemplate.keys(RedisKeyContant.DEVICE_INFO + "*");
        stringRedisTemplate.delete(keys);
        return ResultGenerator.genSuccessResult("删除id:" + id, "删除成功");
    }

    /**
     * 获取运行中设备数量
     *
     * @return
     */
    @Override
    public Result getRunningDeviceCount() {
        QueryWrapper<DeviceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        long count = count(queryWrapper);
        return ResultGenerator.genSuccessResult(count, "获取成功,正在运行中的的设备数量为:" + count);
    }

    /**
     * 获取总数量
     *
     * @return
     */
    @Override
    public Result getDeviceCount() {
        Long count = deviceMapper.selectCount(null);
        return ResultGenerator.genSuccessResult(count, "获取成功,设备总数量为:" + count);
    }
}
